local button = require("button")
local event = require("event")
local draw = require("draw")
local game = require("videopoker")
local component = require("component")
local gpu = component.gpu
local thread = require("thread")
local note = require("note")
local server = require("cdtplib")

--Enum экранов игры
local states = {
	MAIN_MENU = 1,
	SELECT_BET = 2,
	START_ANIMATION = 3,
	SELECT_HOLD = 4,
	FINAL_ANIMATION = 5,
	
}

-- Глобальное состояние игры
local state = states.MAIN_MENU
local prevState = nil
local userId = nil
local balance = 5000
local demo = true
local selectedBet = 0
local deck = {}
local hold = {}

local drawBuffer = {}

--Отрисовка стартового экрана
function mainMenuDraw()
	gpu.setBackground(draw.bgColor)
	local x,y = gpu.getResolution()
	gpu.fill(1,1,x,y," ")
	drawBuffer[2] = draw.card(drawBuffer[2])
	for i = 0,4 do
		gpu.bitblt(0,3+((i)*10),2,50,25,drawBuffer[2])
	end
	gpu.setForeground(draw.fgColor)
	draw.center("Вставьте карту для начала игры",18)
	game.deck()
	mainMenuLock = true

	--Анимация смены карт - причина отдельного потока
	while true do
		for i = 0,4 do
			local card = game.card(i+1)
			drawBuffer[2] = draw.card(drawBuffer[2],card)
			gpu.bitblt(0,3+((i)*10),2,50,25,drawBuffer[2])
			os.sleep(0.7)
		end
	end
end

--Начало игры
function mainMenuLogic(t)
	--Инициализация стартового состояния
	demo = true
	userId = nil
	selectedBet = 6

	event.pull("component_available","drive")
	gpu.fill(1,18,50,1," ")
	draw.center("Загрузка...",18)
	--Загрузка баланса игрока
	local drive = component.drive
	userId = drive.readByte(1)
	local test = server.getBalance(userId) --Предоставляем демо-баланс...
	if not test then balance = 5000 --Если нет соединения
	elseif test == 0 then balance = 5000 --Если баланс ноль
	else
		balance = test
		demo = false
	end
	t:kill() --Убиваем поток с анимацией
	state = states.SELECT_BET --Главное меню => Выбор ставки
end

--Выбор ставки
betDrawStartButton = false
function betDraw()
	drawBuffer[1] = draw.background(selectedBet,drawBuffer[1])
	gpu.bitblt(0,1,1,50,25,drawBuffer[1])
	if selectedBet ~= 6 and betDrawStartButton then
		gpu.fill(1,22,50,1," ")
		gpu.setBackground(draw.fgColor)
		gpu.setForeground(0xFFFFFF)
		gpu.fill(20,22,10,3," ")
		draw.center("НАЧАТЬ",23)
		betDrawStartButton = false
	end
end
function betPredraw()
	gpu.setBackground(draw.bgColor)
	gpu.setForeground(draw.fgColor)
	local x,y = gpu.getResolution()
	gpu.fill(1,1,x,y," ")
	gpu.set(1,12,string.format("Баланс: %d",balance))
	if selectedBet == 6 then
		draw.center("Нажмите на колонку чтобы выбрать ставку",22) end
	betDrawStartButton = true
	drawBuffer[2] = draw.card(drawBuffer[2])
	for i = 0,4 do
		gpu.bitblt(0,3+((i)*10),13,50,25,drawBuffer[2])
	end
end

--Игра завершается, если карта вытащена до начала
local driveListener = nil
function betPrelogic()
	driveListener = event.listen("component_unavailable",
	function(_,name)
		if name ~= "drive" then return end
		state = states.MAIN_MENU
		event.cancel(driveListener)
		event.push("touch",nil,1,1)
	end)
end
--Инициализация кнопок-селекторов ставок
local betButtons = {}
for i=1,5 do
	betButtons[i] = button.create(15+(i*6),2,5,9,0.1,
	function(self)
		if balance >= self.id*100 then
			selectedBet = self.id
			note.play("C1",0.05)
		end
	end,i)
end
--Инициализация кнопки начала игры
local startButton = button.create(19,22,13,3,0.1,function(self)
	if selectedBet > 0 and selectedBet <= 5 then
		state = states.START_ANIMATION
	end
end)
function betLogic()
	local _,_,x,y = event.pull("touch")
	for i=1,5 do
		betButtons[i]:press(x,y)
	end
	startButton:press(x,y)
end

function startLogic()
	game.init()
	deck = game.deck()
	hold = game.hold()
	balance = balance-selectedBet*100
	SELECT = 6
	event.cancel(driveListener)
	driveListener = nil
end

function startAnimation()
	gpu.setBackground(draw.bgColor)
	gpu.fill(19,22,13,3," ")
	gpu.fill(1,12,50,1," ")
	gpu.setForeground(draw.fgColor)
	gpu.set(1,12,string.format("Баланс: %d",balance))
	for i = 1,5 do
		drawBuffer[2] = draw.card(drawBuffer[2],deck[i])
		gpu.bitblt(0,3+((i-1)*10),13,50,25,drawBuffer[2])
		note.play("G1",0.05)
		os.sleep(0.65)
	end
end

local holdButtons = {}
for i = 1,5 do
	holdButtons[i] = button.create(3+((i-1)*10),13,7,8,0.1,
	function(self)
		hold = game.hold{self.id}	
	end,i)
end
local playButton = button.create(20,22,11,3,0.1,
	function(self)
		state = states.FINAL_ANIMATION
	end)
function holdLogic()
	local _,_,x,y = event.pull("touch")
	for i = 1,5 do
		holdButtons[i]:press(x,y)
	end
	playButton:press(x,y)
end

function holdPredraw()
	gpu.set(21,23,"")
end
function holdDraw()
	gpu.setBackground(draw.bgColor)
	gpu.fill(1,13,50,8," ")
	gpu.setBackground(draw.fgColor)
	gpu.setForeground(0xffffff)
	gpu.fill(20,22,11,3," ")
	gpu.set(22,23,"СЫГРАТЬ")
	for i = 1,5 do
		local shift = 0
		if hold[i] then shift = 1 end
		drawBuffer[2] = draw.card(drawBuffer[2],deck[i])
		gpu.bitblt(0,3+((i-1)*10),13+shift,50,25,drawBuffer[2])
	end
end

function finalLogic()
	deck = game.deck()
	hold = game.hold()
end
function finalDraw()
	for i = 1,5 do
		if not hold[i] then
			gpu.setBackground(draw.bgColor)
			gpu.fill(3+((i-1)*10),13,7,7," ")
			note.play("G1",0.05)
			os.sleep(0.65)
		end
	end
	for i = 1,5 do
		if not hold[i] then
			drawBuffer[2] = draw.card(drawBuffer[2],deck[i])
			gpu.bitblt(0,3+((i-1)*10),13,50,25,drawBuffer[2])
			note.play("G1",0.05)
			os.sleep(0.65)
		end
	end
	for i = 1,5 do
		if hold[i] then
			gpu.fill(3+((i-1)*10),14,7,7," ")
			drawBuffer[2] = draw.card(drawBuffer[2],deck[i])
			gpu.bitblt(0,3+((i-1)*10),13,50,25,drawBuffer[2])
		end
	end
end

local test = 0
function endLogic()
	test = game.calc()
	if test > 8 then
		note.play("G4",0.1)
		note.play("B4",0.05)
		note.play("C5",0.05)
		note.play("D5",0.15)
	elseif test > 0 then
		note.play("G4",0.05)
		note.play("G4",0.05)
		note.play("G4",0.05)
	else
		note.play("G4",0.05)
	end
	balance = balance+(selectedBet*100*test)
	if not demo then server.setBalance(userId, balance) end
	if balance == 0 then state = states.MAIN_MENU
	elseif not component.isAvailable("drive") then state = states.MAIN_MENU
	else
		state = states.SELECT_BET
	end
end
function endDraw()
	gpu.setBackground(draw.fgColor)
	gpu.setForeground(draw.bgColor)
	gpu.set(1,12,string.format("Баланс: %d",balance))
	os.sleep(0.7)
	if test > 0 then
		os.sleep(1) end
end

event.timer(60,function()
	if math.random(20) == 1 and state == states.MAIN_MENU then
		note.play("G4",0.1)
		note.play("A4",0.1)
		note.play("C5",0.1)
		note.play("A4",0.1)
		note.play("E5",0.3)
		note.play("E5",0.3)
		note.play("D5",0.6)

		note.play("G4",0.1)
		note.play("A4",0.1)
		note.play("C5",0.1)
		note.play("A4",0.1)
		note.play("D5",0.3)
		note.play("D5",0.3)
		note.play("C5",0.3)
		note.play("B4",0.1)
		note.play("A4",0.2)
	end
end)

while true do
	if state ~= prevState then
		prevState = state
		if state == states.SELECT_BET then
			betPredraw()
			betPrelogic()
		elseif state == states.SELECT_HOLD then
			holdPredraw()
		end
	end
	if state == states.MAIN_MENU then
		game.init()
		local t = thread.create(mainMenuDraw)
		mainMenuLogic(t)
	elseif state == states.SELECT_BET then
		betDraw()
		betLogic()
	elseif state == states.START_ANIMATION then
		startLogic()
		startAnimation()
		state = states.SELECT_HOLD
	elseif state == states.SELECT_HOLD then
		holdDraw()
		holdLogic()
	elseif state == states.FINAL_ANIMATION then
		finalLogic()
		finalDraw()
		state = states.DONE
	elseif state == states.DONE then
		endLogic()
		endDraw()
	end
end
